package com.cxs.musicplaywidget.service.idl;

import com.cxs.musicplaywidget.commonevent.EventManager;
import com.cxs.musicplaywidget.data.EventParam;
import com.cxs.musicplaywidget.player.IMusicPlayer;
import com.cxs.musicplaywidget.player.data.MusicInfo;
import com.cxs.musicplaywidget.player.player.MusicPlayer;
import com.cxs.musicplaywidget.service.DeviceManager;
import com.cxs.musicplaywidget.util.LogUtils;
import ohos.agp.components.LayoutScatter;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;
import ohos.utils.zson.ZSONObject;


import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import static com.cxs.musicplaywidget.constant.Const.IDL.*;
import static com.cxs.musicplaywidget.data.EventParam.EventAction.*;

/**
 * @ClassName MyAgentProxy
 * @author cxs
 * @version 1.0
 * @Description 本地代理(客户端) - 向服务端发送消息
 * @createTime 2022/3/7
*/
public class MyAgentProxy extends AbsRemoteObject implements Cloneable{
    private static final String tag = MyAgentProxy.class.getSimpleName();
    private List<MusicInfo> playList = null;
    private Queue<EventParam> eventParams = new LinkedList<>();
    public int thumbIndex = 1;
    public byte byteIndex;

    public MyAgentProxy(Context context, IRemoteObject remoteObject) {
        super(context, remoteObject);
    }


    public void addEvent(EventParam eventParam) {
        synchronized (eventParams) {
            eventParams.offer(eventParam);
        }
    }

    public void start(EventParam.EventAction eventAction) {
        addEvent(new EventParam(eventAction));
        start();
    }

    public synchronized void start() {
        if (eventParams.isEmpty()) { return; }
        String deviceId = DeviceManager.getInstance(context).getDevice().getDeviceId();
        EventParam eventParam;
        while ((eventParam = eventParams.poll()) != null) {
            System.out.println("eventParam = " + eventParam);
            eventParam.setDeviceIndex(byteIndex);
            EventParam reply = sendMessage(eventParam);
            if (!deviceId.equals("")) {
                EventManager.publishEvent(reply);
            }
        }
    }

    public MusicInfo getMusicInfo() {
        EventParam eventParam = sendMessage(new EventParam(GET_MUSIC_INFO));
        MusicInfo musicInfo = eventParam.getMusicInfo();
        return musicInfo;
    }

    /**
     * 获取远程设备歌曲封面
     * @return
     */
    public byte[] getThumbnail() {
        EventParam eventParam = sendMessage(new EventParam(GET_THUMBNAIL));
        return eventParam.readThumbnail();
    }

    public List<MusicInfo> getPlayList() {
        if (playList == null) {
            try {
                Thread.sleep(500);
                EventParam eventParam = sendMessage(new EventParam(GET_PLAY_LIST, byteIndex));
                playList = eventParam == null ? null : eventParam.getPlayList();
            } catch (InterruptedException e) {
                playList = null;
            }
        }
        return playList;
    }

    public boolean isConnected() {
        EventParam eventParam = sendMessage(new EventParam(IF_CONNECTED));
        return eventParam != null;
    }
    /*
        在本地播放
     */
    EventParam sendMessage(EventParam eventParam) {
        MessageParcel data = MessageParcel.obtain();
        MessageParcel reply = MessageParcel.obtain();
        String zsonString = ZSONObject.toZSONString(eventParam);
        data.writeString(zsonString);
        try {
            remoteObject.sendRequest(REQUEST_CODE, data, reply, new MessageOption(MessageOption.TF_SYNC));
            int errCode = reply.readInt();
            if (errCode == ERR_OK) {
                String s = reply.readString();
                EventParam replyEventParam = ZSONObject.stringToClass(s, EventParam.class);
                if (eventParam.getEventAction() == GET_MUSIC_INFO) {
                    int length = reply.readInt();
                    byte[] bytes = ((length == 0) ? null : reply.readRawData(length));
                    replyEventParam.writeThumbnail(bytes);
                }
                return replyEventParam;
            }
        } catch (RemoteException e) {
            LogUtils.error(tag, "sendMessage.sendRequest failed.");
        }
        return null;
    }

    public void playMusic(MusicInfo musicInfo) {
        IMusicPlayer musicPlayer = MusicPlayer.build(context);
        musicPlayer.start(musicInfo);
        EventParam eventParam = new EventParam(GET_PLAY_LIST, byteIndex);
        eventParam.setPlayList(getPlayList());
        eventParam.setMyPlayIndex(musicInfo.getIndex());
        eventParam.setPlaying(true);
        EventManager.publishEvent(eventParam);
    }

    public void pauseMusic(MusicInfo musicInfo) {
        IMusicPlayer musicPlayer = MusicPlayer.build(context);
        musicPlayer.pause();
        EventParam eventParam = new EventParam(GET_PLAY_LIST, byteIndex);
        eventParam.setPlayList(getPlayList());
        eventParam.setMyPlayIndex(musicInfo.getIndex());
        eventParam.setPlaying(false);
        EventManager.publishEvent(eventParam);
    }

    public MusicInfo getMusicDataFromRemote(MusicInfo musicInfo) {
        String saveFilePath = context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) + File.separator + musicInfo.getName();
        File file = new File(saveFilePath);
        if (file.exists()) {
            LogUtils.debug(tag, "getMusicDataFromRemote.file exists");
            musicInfo.setPath(saveFilePath);
            return musicInfo;
        }

        MessageParcel data = MessageParcel.obtain();
        MessageParcel reply = MessageParcel.obtain();
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(saveFilePath));
            data.writeInt(musicInfo.getIndex());
            remoteObject.sendRequest(REQUEST_GET_MUSIC_DATA_CODE, data, reply, new MessageOption(MessageOption.TF_SYNC));
            int total = reply.readInt();
            byte[] bytes = reply.readRawData(total);
            bos.write(bytes);
            musicInfo.setPath(saveFilePath);
            return musicInfo;
        } catch (RemoteException | IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }



    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }


}
